/**
 * @projectName javacourse
 * @package com.mikeli.javacourse.lesson7.Insert
 * @className com.mikeli.javacourse.lesson7.Insert.TestInsert
 * @copyright Copyright 2020 Thunisoft, Inc All rights reserved.
 */
package com.mikeli.javacourse.lesson7.Insert;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.util.StopWatch;

import cn.hutool.core.date.DateUtil;

/**
 * TestInsert
 *
 * @author lipan
 * @version 1.0
 * @description 1
 * @date 2021/12/17 17:46
 */
public class TestInsert {

    static String url = "jdbc:mysql://127.0.0.1:3306/db_demo?characterEncoding=UTF-8";
    static String user = "root";
    static String pwd = "123456";
    static String sql = "select * from db_demo.t_ddjbxxb limit 1";

    public static void main(String[] args) throws SQLException, ExecutionException, InterruptedException {
//        JdbcConcectTest();
        ConnectionPoolTest();
    }

    static void JdbcConcectTest() throws SQLException {
        ResultSet result = null;
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url, user, pwd);
            statement = connection.prepareStatement(sql);
            result = statement.executeQuery();
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            String sql = "insert into db_demo.t_ddjbxxb values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
            statement = connection.prepareStatement(sql);
            int id = 1;
            for (int i = 0; i < 1000; i++) {
                for (int j = 0; j < 1000; j++) {
                    statement.setString(1, (id++) + "");
                    statement.setString(2, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setString(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setInt(4, 12);
                    statement.setString(5, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setDate(6, new Date(System.nanoTime()));
                    statement.setDate(7, new Date(System.nanoTime()));
                    statement.setString(8, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setString(9, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setString(10, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setInt(11, 12);
                    statement.setString(12, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setString(13, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    statement.setTimestamp(14, new Timestamp(DateUtil.current()));
                    statement.setTimestamp(15, new Timestamp(DateUtil.current()));
                    statement.addBatch();
                }
                statement.executeBatch();
            }
            stopWatch.stop();
            System.out.println(stopWatch.prettyPrint());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (result != null) {
                result.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }

    private static void ConnectionPoolTest() throws SQLException, ExecutionException, InterruptedException {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(url);
        hikariConfig.setUsername(user);
        hikariConfig.setPassword(pwd);
        hikariConfig.setMaximumPoolSize(20);
        hikariConfig.setIdleTimeout(60000);
        HikariDataSource dataSource = new HikariDataSource(hikariConfig);
        ThreadPoolExecutor pool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                Runtime.getRuntime().availableProcessors(),
                60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        AtomicInteger id = new AtomicInteger(0);
        List<CompletableFuture<Number>> results = new ArrayList();
        for (int i = 0; i < 100; i++) {
            CompletableFuture<Number> result = CompletableFuture.supplyAsync(() -> {

                Connection connection = null;
                try {
                    connection = dataSource.getConnection();
                    if(connection.getAutoCommit()){
                        connection.setAutoCommit(false);
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                PreparedStatement statement = null;
                try {
                    String sql = "insert into db_demo.t_ddjbxxb values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
                    statement = connection.prepareStatement(sql);
                    for (int j = 0; j < 10000; j++) {
                        statement.setString(1, (id.getAndIncrement()) + "");
                        statement.setString(2, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setString(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setInt(4, 12);
                        statement.setString(5, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setDate(6, new Date(System.nanoTime()));
                        statement.setDate(7, new Date(System.nanoTime()));
                        statement.setString(8, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setString(9, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setString(10, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setInt(11, 12);
                        statement.setString(12, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setString(13, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                        statement.setTimestamp(14, new Timestamp(DateUtil.current()));
                        statement.setTimestamp(15, new Timestamp(DateUtil.current()));
                        statement.addBatch();
                    }
                    statement.executeBatch();
                    connection.commit();
                    return id;
                } catch (SQLException e) {
                    e.printStackTrace();
                    return -1;
                } finally {
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }, pool);
            results.add(result);
        }
        for (CompletableFuture<Number> r:results
             )
            System.out.println(r.get());
        pool.shutdown();
    }
}
